package com.tsfyun.scm.system.service.impl;

import cn.hutool.core.util.StrUtil;
import com.github.pagehelper.PageInfo;
import com.google.common.collect.Lists;
import com.tsfyun.common.base.constant.CacheConstant;
import com.tsfyun.common.base.exception.ServiceException;
import com.tsfyun.common.base.extension.OrderItem;
import com.tsfyun.common.base.util.TsfPreconditions;
import com.tsfyun.scm.system.dto.CustomsCodeDTO;
import com.tsfyun.scm.system.dto.CustomsQTO;
import com.tsfyun.scm.system.dto.SelectCustomsCodeVO;
import com.tsfyun.scm.system.entity.CustomsCode;
import com.tsfyun.scm.system.entity.Unit;
import com.tsfyun.scm.system.mapper.CustomsCodeMapper;
import com.tsfyun.scm.system.service.ICustomsCodeService;
import com.tsfyun.common.base.extension.ServiceImpl;
import com.tsfyun.scm.system.service.ICustomsElementsService;
import com.tsfyun.scm.system.service.ILevyDutiesService;
import com.tsfyun.scm.system.service.IUnitService;
import com.tsfyun.scm.system.util.TsfWeekendSqls;
import com.tsfyun.scm.system.vo.CustomsCodeDetailVO;
import com.tsfyun.scm.system.vo.CustomsCodeVO;
import com.tsfyun.scm.system.vo.CustomsElementsVO;
import com.tsfyun.scm.system.vo.TariffCustomsCodeVO;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cache.annotation.CacheEvict;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import tk.mybatis.mapper.entity.Example;

import java.math.BigDecimal;
import java.util.List;
import java.util.Objects;
import java.util.Optional;

/**
 * <p>
 *  服务实现类
 * </p>
 *

 * @since 2020-03-19
 */
@Slf4j
@Service
public class CustomsCodeServiceImpl extends ServiceImpl<CustomsCode> implements ICustomsCodeService {

    @Autowired
    private CustomsCodeMapper customsCodeMapper;
    @Autowired
    private ILevyDutiesService levyDutiesService;
    @Autowired
    private IUnitService unitService;
    @Autowired
    private ICustomsElementsService customsElementsService;

    @Override
    public PageInfo<CustomsCode> list(CustomsQTO dto) {
        TsfWeekendSqls sqls = TsfWeekendSqls.<CustomsCode>custom()
                .andLike(true, CustomsCode::getName,dto.getName())
                .andRightLike(true,CustomsCode::getId,dto.getId());
        return super.pageList(dto.getPage(),dto.getLimit(),sqls, Lists.newArrayList(OrderItem.asc("id")));
    }

    @Cacheable(value = CacheConstant.CUSTOMS_DATA_CODE,key = "#id",unless="#result == null")
    @Override
    public CustomsCodeVO detail(String id){
        CustomsCodeVO customsCodeVO = customsCodeMapper.findById(id);
        TsfPreconditions.checkArgument(Objects.nonNull(customsCodeVO),new ServiceException(String.format("海关编码【%s】不存在",id)));
        //查询对美加征关税
        customsCodeVO.setLevyTax(levyDutiesService.taxByHsCode(id));
        return customsCodeVO;
    }

    @Cacheable(value = CacheConstant.ALL_TARIFF_CUSTOMS_CODE,key = "'all'")
    @Override
    public List<TariffCustomsCodeVO> tariffCustoms() {
        List<CustomsCode> customsCodes = customsCodeMapper.selectByExample(Example.builder(CustomsCode.class).where(
                TsfWeekendSqls.<CustomsCode>custom().andGreaterThan(false,CustomsCode::getMfntr, BigDecimal.ZERO)
        ).select("id","mfntr").build());
        return beanMapper.mapAsList(customsCodes,TariffCustomsCodeVO.class);
    }

    @Override
    public List<SelectCustomsCodeVO> selectAll() {
        return customsCodeMapper.findAllShort();
    }

    @CacheEvict(beforeInvocation = true,allEntries = true,value = {CacheConstant.CUSTOMS_DATA_CODE,CacheConstant.ALL_TARIFF_CUSTOMS_CODE})
    @Transactional(rollbackFor = Exception.class)
    @Override
    public void add(CustomsCodeDTO dto) {
        CustomsCode checkCustomsCode = super.getById(dto.getId());
        TsfPreconditions.checkArgument(Objects.isNull(checkCustomsCode),new ServiceException(StrUtil.format("海关编码【{}】已经存在",dto.getId())));
        CustomsCode customsCode = beanMapper.map(dto,CustomsCode.class);
        customsCode.setId(dto.getId());
        Unit unit1 = unitService.getById(dto.getUnitCode());
        Optional.ofNullable(unit1).orElseThrow(()->new ServiceException("单位1错误，请重新选择"));
        customsCode.setUnitName(unit1.getName());
        if(StrUtil.isNotEmpty(dto.getSunitCode())) {
            Unit unit2 = unitService.getById(dto.getSunitCode());
            Optional.ofNullable(unit2).orElseThrow(()->new ServiceException("单位2错误，请重新选择"));
            customsCode.setSunitName(unit2.getName());
        }
        customsCode.setDisabled(false);
        super.saveNonNull(customsCode);
        customsElementsService.deleteAndSaveElementsByHsCode(customsCode.getId(),customsCode.getId(),dto.getElementsName(),dto.getIsNeed());
    }

    @CacheEvict(beforeInvocation = true,allEntries = true,value = {CacheConstant.CUSTOMS_DATA_CODE,CacheConstant.ALL_TARIFF_CUSTOMS_CODE})
    @Transactional(rollbackFor = Exception.class)
    @Override
    public void edit(CustomsCodeDTO dto) {
        CustomsCode checkCustomsCode = super.getById(dto.getId());
        if(Objects.equals(dto.getId(),dto.getPreId()) && Objects.isNull(checkCustomsCode)) { //海关编码未变更
            throw new ServiceException("您要修改的海关编码数据不存在，请确认是否已经删除");
        }
        if(!Objects.equals(dto.getId(),dto.getPreId())) { //海关编码变更
            CustomsCode originCustomsCode = super.getById(dto.getPreId());
            TsfPreconditions.checkArgument(Objects.nonNull(originCustomsCode),new ServiceException("您要修改的海关编码数据不存在，请确认是否已经删除"));
            TsfPreconditions.checkArgument(Objects.isNull(checkCustomsCode),new ServiceException("您输入的海关编码已经存在"));
        }
        CustomsCode customsCode = beanMapper.map(dto,CustomsCode.class);
        customsCode.setId(dto.getId());
        Unit unit1 = unitService.getById(dto.getUnitCode());
        Optional.ofNullable(unit1).orElseThrow(()->new ServiceException("单位1错误，请重新选择"));
        customsCode.setUnitName(unit1.getName());
        if(StrUtil.isNotEmpty(dto.getSunitCode())) {
            Unit unit2 = unitService.getById(dto.getSunitCode());
            Optional.ofNullable(unit2).orElseThrow(()->new ServiceException("单位2错误，请重新选择"));
            customsCode.setSunitName(unit2.getName());
        }
        customsCode.setDisabled(false);
        customsCodeMapper.updateCustomsCode(customsCode,dto.getPreId());
        customsElementsService.deleteAndSaveElementsByHsCode(dto.getPreId(),customsCode.getId(),dto.getElementsName(),dto.getIsNeed());
    }

    @Override
    public CustomsCodeDetailVO info(String id) {
        CustomsCode customsCode = super.getById(id);
        //查询要素信息
        List<CustomsElementsVO> customsElementVOs =  customsElementsService.findByHsCode(customsCode.getId());
        return new CustomsCodeDetailVO(beanMapper.map(customsCode, CustomsCodeVO.class),customsElementVOs);
    }

    @CacheEvict(beforeInvocation = true,allEntries = true,value = {CacheConstant.CUSTOMS_DATA_CODE,CacheConstant.ALL_TARIFF_CUSTOMS_CODE})
    @Transactional(rollbackFor = Exception.class)
    @Override
    public void delete(String id) {
        CustomsCode customsCode = super.getById(id);
        Optional.ofNullable(customsCode).orElseThrow(()->new ServiceException("海关编码信息不存在"));
        //删除要素
        customsElementsService.deleteByCustomsCode(id);
        super.removeById(id);
    }

    @CacheEvict(beforeInvocation = true,allEntries = true,value = {CacheConstant.CUSTOMS_DATA_CODE,CacheConstant.ALL_TARIFF_CUSTOMS_CODE})
    @Override
    public void clear() {
        log.info("清除海关编码缓存成功");
    }


}
